const FMULTI = [1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001];
const MULTI = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000];
const NEGABIT = 0x80000000;

class Dvb {

    static Dvb2Float(dvb) {
        let dot = ((dvb & 0x70000000) >> 28);
        let iv = Dvb2Int(dvb & 0x8FFFFFFF);
        let v = iv * FMULTI[dot];
        return (v);
    }

    static Dvb2Int(dvb) {
        let DECIMUL = [1, 10, 100, 1000, 10000, 100000, 1000000];
        let dot = DotOfDvb(dvb);
        if (dot != 0) {
            dvb >>= (dot * 4);
        }
        let iv = 0;
        for (let i = 0; i < (7 - dot); i++) {
            iv += (dvb & 0x0000000f) * DECIMUL[i];
            dvb >>= 4;
        }
        return ((dvb & 0x00000008) > 0 ? -iv : iv);
    }

    static DotOfDvb(dvb) {
        return ((dvb & 0x70000000) >> 28);
    }

    static Float2Dvb(fv, dot) {
        dot = Math.max(0, dot);
        dot = Math.min(7, dot);
        let mf = fv * MULTI[dot];
        mf = Math.max(-9999999.0, mf);
        mf = Math.min(9999999.0, mf);
        let dvb = Dvb.Int2Dvb(Dvb.Round2Int(mf));
        return (dvb | (dot << 28));
    }

    static Round2Int(f) {
        if (f >= 0.0) {
            return (Number.parseInt(f + 0.4));
        } else {
            return (Number.parseInt(f - 0.4));
        }
    }

    static Int2Dvb(iv) {
        let isNega = (iv < 0);
        if (isNega) {
            iv = -iv;
        }
        let shift = 0;
        let dvb = 0;
        for (let i = 0; i < 7; i++) {
            let deci = iv % 10;
            if (deci != 0) {
                dvb |= (deci << shift);
            }
            iv /= 10;
            shift += 4;
        }
        if (isNega) {
            dvb |= NEGABIT;
        }
        return (dvb);
    }


// 隐含条件：str是一个格式良好的字符串，没有非法字符，顶多有一个小数点，负号一定在首位，有效数字不超过7个
    static String2Dvb(str) {
        let rightIndex = str.length - 1;// 字符串数字右端位置
        let negative = (str[0] == '-') ? 1 : 0;
        let leftIndex = negative ? 1 : 0;		// 字符串数字左端位置
        let dvb = 0x00000000;
        let dotFound = 0;
        let dot = 0;
        for (let i = leftIndex; i <= rightIndex; i++) {		// 从左端高位开始转换，方便移位
            let c = str[i];
            if (c == '.') {					// 遇到小数点
                dotFound = 1;
            } else {							// 遇到数字
                dvb <<= 4;
                dvb |= (c - '0');
                if (dotFound) {
                    dot++;
                }
            }
        }
        if (negative) {
            dvb |= NEGABIT;
        }
        if (dot > 0) {
            dvb |= (dot << 28);
        }
        return (dvb);
    }


}

module.exports = Dvb;

